﻿using System;
using System.Diagnostics;
using System.Text;
using JetBrains.Annotations;



namespace Fine.Utils.Functions
{
    public static class ArrayExt
    {

        public static bool IsNotEmpty<T> (this T[] array)
        {
            return array != null && array.Length > 0;
        }


        public static bool IsEmpty<T> (this T[] array)
        {
            return array == null || array.Length == 0;
        }


        /// <summary>
        /// Excludes one item and decrements the count.
        /// The empty cell will be filled with default value.
        /// </summary>
        /// <typeparam name="T">type of items.</typeparam>
        /// <param name="array">array to exclude item from (should be zero-based); this array will not be reinstantiated.</param>
        /// <param name="index">index of item to exclude.</param>
        /// <param name="count">count of meaningfull items in the array before excluding one; this value will be decremented due to this call.</param>
        /// <returns>excluded item.</returns>
        public static T ExcludeAt<T> ([NotNull] this T[] array, int index, ref int count)
        {
            var length = array.Length;
            if (count > length)
                throw new ArgumentException("ArrayExt.ExcludeAt: count {0} is too large: the array has only {1} elements.".With(count, length));
            if (index >= count)
                throw new ArgumentException("ArrayExt.ExcludeAt: strange arguments: index={0} and count={1}.".With(index, count));

            T excludedItem = array[index];
            count--;

            if (index < count)
                Array.Copy(array, index+1, array, index, count-index);

            array[count] = default(T);

            return excludedItem;
        }


        [NotNull]
        public static String ToString<T>([CanBeNull] this T[] array, 
                                         char delimiter = ',', 
                                         [NotNull] String prefix = "", 
                                         [NotNull] String suffix = "", 
                                         [NotNull] String empty = "")
        {
            if (array == null)
                return empty;

            int n = array.Length;

            switch (n)
            {
                case 0:
                    return empty;
                case 1:
                    return prefix + array[0] + suffix;
                default:
                    StringBuilder buf = new StringBuilder();
                    buf.Append(array[0]);
                    for (int i = 1; i < n; i++)
                        buf.Append(delimiter).Append(array[i]);
                    return buf.ToString();
            }
        }
    }
}
